/*****************************************************************************/
/*!	\file 	IEC61850Types.h
 *	\brief 	IEC 61580 API definition file
	\par        Dalian Yunxing Tech Co., Ltd.

				Dalian, China
				Phone   : +86 (411) 8825 4852
				Email   : yx@yunxing.tech
 */
/*****************************************************************************/

#ifndef IEC61580TYPE_H
#define IEC61580TYPE_H		1

#include "sysctype.h"
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

#define OBJECT_NAME_STRING_LEN 64
#define OBJECT_REFERENCE_STRING_LEN 129
/*!
	\defgroup 	ServerCallback		Server Callback functions
	\defgroup 	ClientCallback 		Client Callback functions
	\defgroup 	ServerAndClientCallback 		Server and Client Callback functions
 */

/*! \enum IEC61850_ErrorCodes
 * 	\brief List of error code returned by API functions
 */
enum IEC61850_ErrorCodes
{
	IEC61850_ERROR_NONE									= 0,		/*!< Everything was ok */
	IEC61850_ERROR_INVALID_PARAMETERS 					= -1,		/*!< Supplied parameters are invalid */
	IEC61850_ERROR_NO_MEMORY 							= -2,		/*!< Allocation of memory has failed */
	IEC61850_ERROR_SCL_FILE_OPEN_FAILED 				= -3,		/*!< Provided SCL file failed to open, check the path and file name are correct */
	IEC61850_ERROR_SERVICE_FAILED		 				= -4,		/*!< Service failed to start */
	IEC61850_ERROR_SCL_SYNTAX_ERROR		 				= -5,		/*!< SCL File Failed to parse due to syntax error */
	IEC61850_ERROR_SCL_IO_ERROR		 					= -6,		/*!< SCL File Failed to parse due IO error */
	IEC61850_ERROR_SCL_NO_IED_CONNECTEDAP				= -7,		/*!< Can't find a matching ConnectedAP for this IED */
	IEC61850_ERROR_TYPE_MISMATCH						= -8,		/*!< The Type you are trying to write/update does not match the type in the server/client */
	IEC61850_ERROR_LICENCE_INVALID						= -9,		/*!< The licence file is not valid or present */
	IEC61850_ERROR_DATA_ATTRIBUTE_ID_NOT_FOUND			= -10,		/*!< The given Data Attribute ID was not found in the loaded SCL file */
	IEC61850_ERROR_DATA_ATTRIBUTE_ID_NO_CONNECTION		= -11,		/*!< There is no ready connection to given Data Attribute ID */
	IEC61850_ERROR_SCL_LN_TYPE_NOT_FOUND				= -12,		/*!< The LN Type specified in the LN element was not found in the data template */
	IEC61850_ERROR_SCL_DATASET_NOT_FOUND				= -13,		/*!< The Dataset specified in a the control block was not found */
	IEC61850_ERROR_SCL_GSE_COMM_NOT_FOUND				= -14,		/*!< The GSE Communication access point specified in a the control block was not found */
	IEC61850_ERROR_SCL_SV_COMM_NOT_FOUND				= -15,		/*!< The Sampled Value Communication access point specified in a the control block was not found */
	IEC61850_ERROR_SCL_INVALID_MAC_ADDRESS				= -16,		/*!< The SCL contains a Invalid MAC address */
	IEC61850_ERROR_GOOSE_INIT_FAILED					= -17,		/*!< GOOSE Service failed to initialise */
	IEC61850_ERROR_SV_INIT_FAILED						= -18,		/*!< Sampled Value Service failed to initialise */
	IEC61850_ERROR_MMS_INIT_FAILED						= -19,		/*!< The MMS Service failed to initialise  */
	IEC61850_ERROR_SCL_DATA_TYPE_TEMPLATE_NAME			= -20,		/*!< Missing or invalid Data type name in Data Type Template  */
	IEC61850_ERROR_SCL_DATA_TYPE_TEMPLATE_ID			= -21,		/*!< Missing or invalid Data type ID in Data Type Template  */
	IEC61850_ERROR_SCL_DATASET_NAME						= -22,		/*!< Missing or invalid Data set Name  */
	IEC61850_ERROR_SCL_IED_ELEMENT_NAME					= -23,		/*!< Missing or Invalid IED element name (eg name attribute for IED, LD, LN, DOI, SDI or DAI) */
	IEC61850_ERROR_SCL_COMM_NAME						= -24, 		/*!< Missing or Invalid Communication element name  */
	IEC61850_ERROR_INVALID_STATE						= -25, 		/*!< The function cannot be performed while the client/server object is in the current state */
	IEC61850_ERROR_SCL_DATASET_FCDA_NOT_FOUND			= -26, 		/*!< The Functional Constrained Data Attribute in the dataset cannot be found */
	IEC61850_ERROR_SCL_DUPLICATE_LD						= -27, 		/*!< Two or more LDs have the same name. LDs names must be unique */
	IEC61850_ERROR_SCL_LD_NO_NAME 						= -28,		/*!< A Logical Device has no name. LD must have a name. */
	IEC61850_ERROR_SCL_LD_NO_LNS 						= -29,		/*!< The logical device has no Logical Nodes. LDs must have one Logical Node */
	IEC61850_ERROR_SCL_DUPLICATE_LN						= -30, 		/*!< Two or more LNs have the same name within a LD. LN names must be unique within a LD */
	IEC61850_ERROR_SCL_DUPLICATE_DOTYPES				= -31,		/*!< The DataType template contains duplicated DO Types. */
	IEC61850_ERROR_SCL_DUPLICATE_DATYPES				= -32,		/*!< The DataType template contains duplicated DA Types. */
	IEC61850_ERROR_SCL_DUPLICATE_ENUMTYPE				= -33, 		/*!< The DataType template contains duplicated Enumerated Types  */
	IEC61850_ERROR_SCL_DUPLICATE_LNTYPES				= -34, 		/*!< The DataType template contains duplicated Logical Node Types  */
	IEC61850_ERROR_SCL_DUPLICATE_LNTYPE_DO_NAME			= -35, 		/*!< The DataType template contains duplicated Data Objects within a Logical Node Type */
	IEC61850_ERROR_SCL_LNTYPE_DO_NO_NAME				= -36,		/*!< The Data Object within a logical node type has no name */
	IEC61850_ERROR_SCL_LNTYPE_NO_DOS					= -37,		/*!< The Logical Node type within the data type template has no data objects */
	IEC61850_ERROR_SCL_DUPLICATE_DOTYPE_DA_NAME			= -38,		/*!< A Data Attribute within a Data Object type with the data type template has a name which is not unique */
	IEC61850_ERROR_SCL_DUPLICATE_DOTYPE_SDO_NAME		= -39,		/*!< A Sub Data object within a Data Object type with the data type template has a name which is not unique */
	IEC61850_ERROR_SCL_DUPLICATE_DATYPE_BDA_NAME		= -40,		/*!< A Basic Data Attribute within a Data attribute type with the data type template has a name which is not unique */
	IEC61850_ERROR_GOOSE_CONTROL_BLOCK_INVALID			= -41,		/*!< One of the GOOSE Control blocks is not valid and can't be started */
	IEC61850_ERROR_SCL_DUPLICATE_DA_ID					= -42,		/*!< There are two or more Data attributes that have the same DA ID (Private field) */
	IEC61850_ERROR_CONTROL_NOT_ACTIVE					= -43,		/*!< The given control is not active, or no control is active */
	IEC61850_ERROR_SCL_CONTROL_MODEL_INVALID			= -44,		/*!< The given control model found in the SCL file is not valid, ensure all mandatory DAs are present in the control */
	IEC61850_ERROR_SCL_DAI_WITHOUT_DA_TYPE				= -45,		/*!< A Data Attribute (DAI) has no matching Data attribute type (DA) */
	IEC61850_ERROR_SCL_CLIENT_TOO_FEW_IEDS				= -46,		/*!< The SCD file does not contain 2 or more IEDs (Minimum of one IED for the client and one IED for a server) */
	IEC61850_ERROR_SERVICE_UNSUPPORTED					= -47,		/*!< A Service (eg GOOSE, MMS, Reports, SampleValue, Logging) is unsupported */
	IEC61850_ERROR_SV_CONTROL_BLOCK_INVALID				= -48,		/*!< One of the SV Control blocks is not valid and can't be started */
	IEC61850_ERROR_MMS_COMMS_FAILED						= -49,		/*!<  MMS layer Communication failed*/
	IEC61850_ERROR_MMS_SAP_FAILED						= -50,		/*!< Unable to create a service access point for the MMS server, ensure Connected AP \<Address\> has correct, OSI-PSEL, OSI-SSEL, OSI-TSEL, OSI-AE-Qualifier and OSI-AP-Title  */
	IEC61850_ERROR_ARRAY_INDEX_INVALID					= -51,		/*!< The Array index specified is Invalid. Array does not contain this Index Element */
	IEC61850_ERROR_OPERATIVE_TEST_CALLBACK_NOT_SET		= -52,		/*!< Operative test call back is not set for Controls on Server Side*/
	IEC61850_ERROR_OPERATE_CALLBACK_NOT_SET				= -53,		/*!< Operate call back is not set for Controls on Server Side*/
	IEC61850_ERROR_SCL_INVALID_TRIGGER_CONDITION		= -54,		/*!< Trigger condition set for control block is invalid*/
	IEC61850_ERROR_SCL_INVALID_REPORT_CONTROL_BLOCK		= -55,		/*!< Indexed Attribute for Report Control Block is set to FALSE but Max Report Enabled is set to more than 1*/
	IEC61850_ERROR_INVALID_IP_ADDRESS					= -56,		/*!< Invalid IP Address Point  */
	IEC61850_ERROR_SERVICE_REJECTED						= -57,		/*!< A Service (eg GOOSE, MMS, Reports, SampleValue, Logging) rejected the command */
	IEC61850_ERROR_EDITION1_OR_EDITION2_FLAG_NOT_SET	= -58,		/*!< Specify IEC61850 Edition1 or IEC61850 Edition2 */
	IEC61850_ERROR_SCL_MISSING_DO_TYPE_MEMORY			= -59,		/*!< DO Type detected as NULL when navigating SCL tree, currently generated when looking for Transient*/
	IEC61850_ERROR_ARRAY_UPDATE_FAILED					= -60,		/*!< Attempting to update the array values in the stack failed*/
	IEC61850_ERROR_BITLENGTH_MISMATCH					= -61,		/*!< Length passed in from user application does not match length in the stack*/
	IEC61850_ERROR_SELECT_RESPONSE_INVALID				= -62,		/*!< Response from 'Select' read was invalid*/
	IEC61850_ERROR_SELECT_MMS_FAILED					= -63,		/*!< MMS Error Generated when read generated as part of Select*/
	IEC61850_ERROR_GOOSE_DEINITIALIZE_FAILED			= -64,		/*!< GOOSE Service failed to shutdown*/
	IEC61850_ERROR_MMS_DEINITIALIZE_FAILED				= -65,		/*!< MMS Service failed to shutdown*/
	IEC61850_ERROR_SAMPLED_VALUES_DEINITIALIZE_FAILED	= -66,		/*!< SV Service failed to shutdown*/
	IEC61850_ERROR_REPORTING_DEINITIALIZE_FAILED		= -67,		/*!< Reporting Service failed to shutdown*/
	IEC61850_ERROR_CONTROLS_DEINITIALIZE_FAILED			= -68,		/*!< Controls Service failed to shutdown*/
	IEC61850_ERROR_CONTROL_BLOCK_DEINITIALIZE_FAILED	= -69,		/*!< Control block failed to deinitialse*/
	IEC61850_ERROR_LOGGING_DEINITIALIZE_FAILED			= -70,		/*!< Logging Service failed to shutdown*/
	IEC61850_ERROR_FREE_DATA_FAILED						= -71,		/*!< Unable to free memory*/
	IEC61850_ERROR_MMS_SERVICE_FAILED					= -72,		/*!< MMS Service failed to start*/
	IEC61850_ERROR_GOOSE_SERVICE_FAILED					= -73,		/*!< GOOSE Service failed to start*/
	IEC61850_ERROR_SAMPLED_VALUE_SERVICE_FAILED			= -74,		/*!< Sampled Value Service failed to start*/
	IEC61850_ERROR_LOGGING_SERVICE_FAILED				= -75,		/*!< Logging Service failed to start*/
	IEC61850_ERROR_SCL_NO_DAID							= -76,		/*!< SCL file does not have any DAIDs defined*/
	IEC61850_ERROR_FUNCTION_NOT_SUPPORTED				= -77,		/*!< This function is not supported on this platform, or that stack is in the wrong Server or Client mode*/
	IEC61850_ERROR_ENTRYID_SET_ON_URCB_CB				= -78,		/*!< Entry ID field has been set on Unbuffered Report Control Block*/
	IEC61850_ERROR_CONTROL_REJECTED						= -79,		/*!< Response from Server was Object Access Denied, check Last App error*/
	IEC61850_ERROR_SV_GOOSE_CONTROL_BLOCK_CONFLICT		= -80,		/*!< Sampled Value not supported when GOOSE control blocks present*/
	IEC61850_ERROR_EXTREF_DAI_NOT_FOUND					= -81,		/*!< The Internal or External DAI was not found when linking External references*/
	IEC61850_ERROR_MMS_TIMEOUT							= -82,		/*!< The MMS layer timed out*/
	IEC61850_ERROR_MMS_FILE_ERROR						= -83,		/*!< The MMS Server responded with an error*/
	IEC61850_ERROR_FILE_SYSTEM_ERROR					= -84,		/*!< An error occurred trying to read or write to the file system*/
	IEC61850_ERROR_GOOSE_SUB_DISABLED					= -85,		/*!< GOOSE Subscription create parameter flag (IEC61850_OPTION_SERVER_SUBSCRIBE_GOOSE) was not set during create*/
	IEC61850_ERROR_NO_CONTROLS_FOUND					= -86,		/*!< No Controls were found in the SCL file, API could not complete the given task*/
	IEC61850_ERROR_ID_DOES_NOT_MATCH_ACTIVE_CONTROL		= -87,		/*!< The Specified ID does not match the ID of the Active (last Operated) Control*/
	IEC61850_ERROR_INVALID_ORIGIN_IDENT_SIZE			= -88,		/*!< Invalid OrIdent String Size */
	IEC61850_ERROR_UPDATE_FAILED_VALUE_NOT_SUPPORTED	= -89,		/*!< The new value to be updated is not supported for the data point. The type or size maybe invalid or the IEC61850 logic layer has blocked the data update */
	IEC61850_ERROR_SCL_INVALID_FC						= -90,		/*!< SCL File have an Invalid Functional Constraint*/
	IEC61850_ERROR_SETTING_GROUP_CONTROL_EMPTY			= -91,		/*!< The Setting Group Control Block has NO Data attributes associated with it, i.e. no SP DAs with an sGroup set*/
	IEC61850_ERROR_SCL_CONTROL_DA_UNSUPORTED			= -92,		/*!< SCL File has an unsupported DA in a control Oper or SBOw, check that OperTm is not present */
	IEC61850_ERROR_DATASET_MAX_ATTRIBUTES				= -93,		/*!< A dataset has more FCDAs than the services ConfDataSet maxAttributes specifies  */
	IEC61850_ERROR_DATASET_MAX							= -94,		/*!< SCL File has more datasets than the services ConfDataSet max specifies */
	IEC61850_ERROR_SCL_MULTIPLE_DAIDS					= -95,		/*!< SCL File has multiple DA IDs on a single point DA. Only one is allowed */
	IEC61850_ERROR_INFO_START_AT_INVALID				= -96,		/*!< The Start at value is larger than the number of DAs loaded into the stack */
	IEC61850_ERROR_OBJECT_NON_EXISTENT					= -97,		/*!< Object does not exist on the remote server (usually from MMS Access Result Object-Non-Existent ) */
	IEC61850_ERROR_SCL_DUPLICATE_GOCB_ID                = -98,		/*!< There are two or more goose that have the same CB ID (Private field) */
	IEC61850_ERROR_SCL_DUPLICATE_RPTCB_ID               = -99,		/*!< There are two or more reports that have the same CB ID (Private field) */

};

/*! Byte Size of OrIdent IEC61850-7-3 Section6.8 Table 7  */
#define CONTROL_ORIGIN_IDENT_SIZE 64 
#define CONTROL_TIME_SIZE 8

/*! Values of Originator Category as defined in IEC61850-7-3 Section6.8 Table 8 */ 
enum eOriginatorCat
{
	ORCAT_NOT_SUPPORTED			= 0, /*!< orCat is not supported */
	ORCAT_BAY_CONTROL			= 1, /*!< Control operation issued from an operator using a client located at bay level */
	ORCAT_STATION_CONTROL		= 2, /*!< Control operation issued from an operator using a client located at station level */
	ORCAT_REMOTE_CONTROL		= 3, /*!< Control operation from a remote operater outside the substation (for example network control center) */
	ORCAT_AUTOMATIC_BAY			= 4, /*!< Control operation issued from an automatic function at bay level */
	ORCAT_AUTOMATIC_STATION		= 5, /*!< Control operation issued from an automatic function at station level */
	ORCAT_AUTOMATIC_REMOTE		= 6, /*!< Control operation issued from a automatic function outside of the substation */
	ORCAT_MAINTENANCE			= 7, /*!< Control operation issued from a maintenance/service tool */
	ORCAT_PROCESS				= 8, /*!< Status change occurred without control action (for example external trip of a circuit breaker or failure inside the breaker) */
};

/*! IEC 61850 Data Attribute IDs   */
enum IEC61850_DataAttributeIDs
{
	IEC61850_DAID_IEC101 		= 1,	/*!< IEC101 protocol - \deprecated  */
	IEC61850_DAID_IEC103 		= 2,	/*!< IEC103 protocol - \deprecated */
	IEC61850_DAID_IEC104 		= 3,	/*!< IEC104 protocol - \deprecated */
	IEC61850_DAID_MODBUS		= 4,	/*!< ModBus protocol - \deprecated */
	IEC61850_DAID_DNP3			= 5,	/*!< DNP3 protocol - \deprecated */
	IEC61850_DAID_GENERIC		= 6,	/*!< Generic protocol */
	IEC61850_DAID_SYSTEMCORP	= 7,	/*!< SystemCorp Objects */
	IEC61850_DAID_DAP			= 8,	/*!< DAP Objects - \deprecated */
};

/*!	\brief daid_t type*/
typedef unsigned int daid_t;

/*!	\brief DAID COMMON Prefix*/
#define __DAID_COMMON(daid_prefix)  \
	daid_t daid_prefix##type

/*!	\brief  Size of  daid_prefix */
#define __DAID_COMMON_SIZE  (sizeof (unsigned int))

/*!	\brief 		This structure hold the identification of a IEC61850 data Attribute. This is used to type cast from other Data Attributes ID Types. */
struct IEC61850_DataAttributeID
{
	__DAID_COMMON(daid_);			/*!< Common data attribute ID */
	char DAID_data[5*sizeof(unsigned int)]; 	/*!<  Common data */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a Generic ID. 
 *			It is recommended to use this type of ID on all data points 
 */
struct IEC61850_DataAttributeID_Generic
{
	__DAID_COMMON(Generic_);		/*!< This should be set to IEC61850_DAID_GENERIC  */
	unsigned int 	uiField1;		/*!< Generic Protocol Field value 1 */
	unsigned int 	uiField2;		/*!< Generic Protocol Field value 2 */
	unsigned int 	uiField3;		/*!< Generic Protocol Field value 3 */
	unsigned int 	uiField4;		/*!< Generic Protocol Field value 4 */
	unsigned int 	uiField5;		/*!< Generic Protocol Field value 5 */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a DNP3 ID.
 *			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
 */
struct IEC61850_DataAttributeID_DNP3
{
	__DAID_COMMON(DNP3_); 	/*!< This should be set to IEC61850_DAID_DNP3  */
	unsigned int 	uiDatatype;			/*!< DataType for DNP3 */
	unsigned int 	uiObjectno;			/*!< Object Number for DNP3 */
	char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (2*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a IEC 101 object ID. 
*			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
*/
struct IEC61850_DataAttributeID_IEC101
{
	__DAID_COMMON(IEC101_);	/*!< This should be set to IEC61850_DAID_IEC101  */
	unsigned int 	uiCASDU;			/*!< Common Address of SDU */
	unsigned int 	uiIOA;				/*!< Information Object Address */
	unsigned int 	uiTI;				/*!< Type Identification */
	unsigned char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (3*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a IEC 103 object ID. 
*			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
*/
struct IEC61850_DataAttributeID_IEC103
{
	__DAID_COMMON(IEC103_);	/*!< This should be set to IEC61850_DAID_IEC103  */
	unsigned int 	uiRTUaddr;			/*!< RTU Address */
	unsigned int 	uiIOA;				/*!< Information Object Address */
	unsigned int 	uiTI;				/*!< Type Identification */
	unsigned char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (3*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a IEC 104 object ID. 
*			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
*/
struct IEC61850_DataAttributeID_IEC104
{
	__DAID_COMMON(IEC104_);	/*!< This should be set to IEC61850_DAID_IEC104  */
	unsigned int 	uiCASDU;			/*!< Common Address of SDU */
	unsigned int 	uiIOA;				/*!< Information Object Address */
	unsigned int 	uiTI;				/*!< Type Identification */
	unsigned char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (3*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a DAP object ID. 
*			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
*/
struct IEC61850_DataAttributeID_DAP
{
	__DAID_COMMON(DAP_);	/*!< This should be set to IEC61850_DAID_IEC104  */
	unsigned int 	uiID;			/*!< ID */
	unsigned int 	uiType;			/*!< Type */
	unsigned char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (2*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*! \brief enum used to refer to the type of a Control Block ID */
enum ControlBlockTypes
{
	CONTROLBLOCK_GOOSE,		
	CONTROLBLOCK_REPORT,	
	CONTROLBLOCK_LOG,		
	CONTROLBLOCK_SV,		
};

/*!	\brief 	This structure hold the identification of a IEC61850 Control Block ID. 
*/
struct IEC61850_ControlBlockID
{
	enum ControlBlockTypes	controlBlockType;	/*!< This is used to determine the type of control block this ID reffers to; GOOSE, Reports, SV or Logging  */
	Unsigned32 	uiField1;		/*!< Control Block ID Field value 1 */
	Unsigned32 	uiField2;		/*!< Control Block ID Field value 2 */
	Unsigned32 	uiField3;		/*!< Control Block ID Field value 3 */
	Unsigned32 	uiField4;		/*!< Control Block ID Field value 4 */
	Unsigned32 	uiIndex;		/*!< Control Block Index used to reference Report control block instances that are Automatic Indexed*/
};

/*!	\brief 	struct IEC61850_DataAttributeID_ModBus.uiDataType Values 	*/
enum ModBusDataTypes
{
	MODBUS_DATATYPE_DISCRETE_INPUT			= 1,	 /*!< A Discrete input */
	MODBUS_DATATYPE_INPUT_REGISTER			= 2,	 /*!< A input Register */
	MODBUS_DATATYPE_COIL 						= 3,	 /*!< A Coil output */
	MODBUS_DATATYPE_HOLDING_REGISTER		= 4, /*!< A Holding Register output */
};
/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a ModBus ID. 
*			This is a deprecated private ID type that is only for use with SystemCORP's legacy WebCan systems.
*/
struct IEC61850_DataAttributeID_ModBus
{
	__DAID_COMMON(ModBus_);	/*!< This should be set to IEC61850_DAID_MODBUS  */
	unsigned int 	uiSlaveAddress;		/*!< Slave Address in ModBus */
	unsigned int 	uiDataAddress;		/*!< DataAddress in ModBus */
	unsigned int 	uiDataType;			/*!< DataType in ModBus (see #ModBusDataTypes for values) */
	unsigned char zero[sizeof (struct IEC61850_DataAttributeID) - __DAID_COMMON_SIZE - (3*sizeof (unsigned int))]; /*!< Unused Data. This should be set to zero */
};

/*!	\brief 	struct IEC61850_DataAttributeID_SystemCORP.uiField Values 	*/
enum SystemCORP_Fields
{
	PIS10_FIELDS_DATA 						= 0,	 /*!< Data Field */
	PIS10_FIELDS_STATUS					= 1,	 /*!< Status Field */
	PIS10_FIELDS_TIMESTAMP				= 2,	 /*!< Time Stamp Field */
	PIS10_FIELDS_SELECT 					= 3,	 /*!< Select Field */
	PIS10_FIELDS_OPERATE					= 4, /*!< Operate Field */
	PIS10_FIELDS_CANCEL					= 5, /*!< Cancel Field */
	PIS10_FIELDS_COMMAND_TERMINATION	= 6, /*!< Command Termination Field */
};
/*!	\brief 	This structure hold the identification of a IEC61850 Data Attribute with a SystemCORP ID. 
 *			This type of Private ID is for use with SystemCORP's ADH and eNode Designer software
 */
struct IEC61850_DataAttributeID_SystemCORP
{
	__DAID_COMMON(SystemCORP_);	/*!< This should be set to IEC61850_DAID_PIS10  */
	unsigned int 	uiCFENumber;			/*!< The ID Number of the CFE that this data belongs. (Equal to CFENo attribute in the PIS10 schema) */
	unsigned int 	uiClass;					/*!< The Data Class of this data instance (Equal to Class attribute in the PIS10 schema) */
	unsigned int 	uiNumber;				/*!< The Object number of this data instance  (Equal to Number attribute in the PIS10 schema)*/
	unsigned int 	uiField;					/*!< The data field this data belongs. (Data, Stauts, Timestamp, Select and Operate) see #SystemCORP_Fields (Equal to Field attribute in the PIS10 schema) */
	unsigned int 	uiCommandPort;			/*!< The Command Port of this object */
};

/*!	\brief 		A Data object structure. Used to exchange data objects between IEC61850 object and application. */
struct IEC61850_DataAttributeData
{
	unsigned char ucType;			/*!< Type of data. Values can from #IEC61850_DataTypes */
	int iArrayIndex;				/*!< Index specifier for an Array Element being accessed*/
	unsigned int uiBitLength;		/*!< Bit Length of data at pvData (NOTE: This is in Bits! So one octel equal to 8)*/
	void * pvData;					/*!< Pointer to data of length equal to uiBitLength bits */
};

#define IEC61850_ERROR_STRING_SIZE	256	//!< Length of strings in #IEC61850_ErrorParameters

/*!	\brief 		IEC61850 Error Parameters structure. */
struct IEC61850_ErrorParameters
{
	char uDomainName[IEC61850_ERROR_STRING_SIZE];  /*!< Domain Name string */
	char uItemName[IEC61850_ERROR_STRING_SIZE];	/*!< Item Name string */
	char uErrorType[IEC61850_ERROR_STRING_SIZE];	/*!< Error Type string */
	Unsigned8 iErrorType;	/*!< Enumerated value of the Error Type */
	char uErrorCause[IEC61850_ERROR_STRING_SIZE];	/*!< Error Cause string */
	Unsigned8 iErrorCause;	/*!< Enumerated value of the Error Cause */
};

/*!	IEC61850 Data Types (see IEC 61850-7-2:2003 section 5.5.2)  */
enum IEC61850_DataTypes
{
	IEC61850_DATATYPE_BOOLEAN			= 1,		/*!< Data is of type Boolean. If value is equal to 0 then false, otherwise it true  */
	IEC61850_DATATYPE_INT8				= 2,		/*!< An integer of 8 bits.  */
	IEC61850_DATATYPE_INT16				= 3,		/*!< An integer of 16 bits. */
	IEC61850_DATATYPE_INT32				= 4,		/*!< An integer of 32 bits.  */
	IEC61850_DATATYPE_INT64				= 5,		/*!< An integer of 64 bits */
	IEC61850_DATATYPE_INT8U				= 6,		/*!< An unsigned integer of 8 bits. */
	IEC61850_DATATYPE_INT16U			= 7,		/*!< An unsigned integer of 16 bits. */
	IEC61850_DATATYPE_INT32U			= 8,		/*!< An unsigned integer of 32 bits. */
	IEC61850_DATATYPE_FLOAT32			= 9,		/*!< An IEEE 754 single precision floating point */
	IEC61850_DATATYPE_FLOAT64			= 10,		/*!< An IEEE 754 double precision floating point */
	IEC61850_DATATYPE_ENUMERATED		= 11,		/*!< Ordered set of values. extended allowed */
	IEC61850_DATATYPE_CODED_ENUM		= 12,		/*!< Ordered set of values. Not allowed to be extended */
	IEC61850_DATATYPE_OCTEL_STRING		= 13,		/*!< A String of Octels charactures  */
	IEC61850_DATATYPE_VISIBLE_STRING	= 14,		/*!< A String of Visible charactures  */
	IEC61850_DATATYPE_UNICODE_STRING	= 15,		/*!< A String of Unicode charactures  */
	IEC61850_DATATYPE_TIMESTAMP			= 16,		/*!< TimeStamp type (5.5.3.7.1 of IEC 61850-7-2:2003) */
	IEC61850_DATATYPE_QUALITY			= 17,		/*!< Quality data type. This a big endian bitstring as defined in enum IEC61850QualityFlags */
	IEC61850_DATATYPE_ARRAY				= 18,		/*!< An array type */
	IEC61850_DATATYPE_STRUCTURE			= 19,		/*!< A structure type */
};

/*!	tServerStatusArray  defined as struct IEC61850_ServerStatusArray */
#define tServerStatusArray struct IEC61850_ServerStatusArray *	/*!< redeclaration for parameter passing purposes */

/*!	IEC61850 Server Status Val */
enum IEC61850_ServerStatusVal
{
	SERVER_STATUS_UNKNOWN		=0,	/*!<  Initialised value, status not known yet*/
	SERVER_STATUS_CONNECTED		=1,	/*!<  Server is connected, and communicating*/
	SERVER_STATUS_DISCONNECTED	=2,	/*!<  Server is disconnected*/
	SERVER_STATUS_CONNECTING	=3,	/*!<  Client is connecting to server*/
	SERVER_STATUS_DISCONNECTING =4,	/*!<  Client is disconnecting from server*/
};



/*!	\brief  	Number of bits used in Boolean type 	 */
#define IEC61850_BOOLEAN_BITSIZE	8

/*!	\brief  	Size of struct IEC61850TimeStamp 	 */
#define IEC61850_TIMESTAMP_BITSIZE	64

/*!	\brief 	IEC61850 NTP Time Stamp Structure (as specified in IEC61850_DATATYPE_TIMESTAMP)	 */
struct IEC61850_TimeStamp
{
	Unsigned32		u32Seconds;				/*!< Number of Seconds */
	Unsigned32		u32FractionsOfSecond;	/*!< Fraction of a second as a binary fraction. The 3 MSB store the fractions of the second, and the LSB stores the time quality */
};

/*!	\brief 	IEC61850 Server Status Structure Contains Connected Server Status */
struct IEC61850_ServerStatus
{
	char		*					ai8IP_Addr;		/*!< IP address of the server we are reporting the status for */
	char		*					IedName;		/*!< IED name of the server we are reporting the status for */
	Integer32						OSErrorCode;	/*!< Any OS based Error Codes not handled by the stack */
	enum IEC61850_ServerStatusVal	isConnected;	/*!< Server connection status */
};


/*!	\brief 	IEC61850 Server Status Array Structure Contains Connected Array of Server Statuses */
struct IEC61850_ServerStatusArray
{
	struct IEC61850_ServerStatus * ServerStatusArray;	/*!< Array of all the servers specified in the client CID file, do not free this pointer */
	int ServerStatusArraySize;		/*!< count of all the servers specified in the client CID file */
};


/*!  IEC61850 Quality flags. (see IEC 61850-8-1:2004 section 8.2)  */
enum IEC61850TimeQualityFlags
{
	IEC61850_TIMEQUALITY_LEAP_SECOND_KNOWN				= 0x0000000080,	/*!< Leap second known flag */
	IEC61850_TIMEQUALITY_CLOCK_FAILURE					= 0x0000000040,	/*!< Clock failure flag */
	IEC61850_TIMEQUALITY_CLOCK_NOT_SYNCHRONIZED			= 0x0000000020,	/*!< Clock not syncronised flag */
	IEC61850_TIMEQUALITY_0_BIT_OF_ACCURACY				= 0x0000000000,	/*!< 0 bit accuracy flag */
	IEC61850_TIMEQUALITY_1_BIT_OF_ACCURACY				= 0x0000000001,	/*!< 1 bit accuracy flag */
	IEC61850_TIMEQUALITY_24_BIT_OF_ACCURACY				= 0x0000000018,	/*!< 24 bit accuracy flag */
	IEC61850_TIMEQUALITY_ACCURACY_UNSPECIFIED			= 0x000000001F,	/*!< Accuracy unspecified flag */
};

/*!	\brief  	Number of bits used in Quality flag 	 */
#define IEC61850_QUALITY_BITSIZE	13

/*!	\brief 	IEC61850 Quality data type. (as specified in #IEC61850QualityFlags) */
typedef Unsigned16 tIEC61850Quality;

#ifdef __BIGENDIAN__

/*!	IEC61850 Quality flags. (see IEC 61850-8-1:2004 section 8.2) */
enum IEC61850QualityFlags
{
	IEC61850_QUALITY_GOOD			= 0x0000,	/*!< Good */
	IEC61850_QUALITY_INVALID		= 0x4000,	/*!< Invalid */
	IEC61850_QUALITY_RESERVED		= 0x8000,	/*!< Reserved */
	IEC61850_QUALITY_QUESTIONABLE	= 0xC000,	/*!< Questionable */
	IEC61850_QUALITY_OVERFLOW		= 0x2000,	/*!< Overflow */
	IEC61850_QUALITY_OUTOFRANGE 	= 0x1000,	/*!< Out of Range */
	IEC61850_QUALITY_BADREFERENCE	= 0x0800,	/*!< Bad Reference */
	IEC61850_QUALITY_OSCILLATORY	= 0x0400,	/*!< Oscillatory */
	IEC61850_QUALITY_FAILURE		= 0x0200,	/*!< Failure */
	IEC61850_QUALITY_OLDDATA		= 0x0100,	/*!< Old Data */
	IEC61850_QUALITY_INCONSISTENT	= 0x0080,	/*!< Inconsistent */
	IEC61850_QUALITY_INACCURATE		= 0x0040,	/*!< Inaccurate */
	IEC61850_QUALITY_SUBSTITUED		= 0x0020,	/*!< Substitued if not set then Source is from the process */
	IEC61850_QUALITY_TEST			= 0x0010,	/*!< Test */
	IEC61850_QUALITY_OPERATOR_BLOCKED	= 0x0008,	/*!< Blocked by Operator */
	IEC61850_QUALITY_SV_DER	= 0x0004,	/*!< Derived Quality for Sampled Values ONLY, Der field is an identifier of the derived current sampled value. Der should be set when the value is calculated and not a measurement */
};

/*!	\brief  	Bit mask of Validity flags (IEC61850_QUALITY_GOOD, IEC61850_QUALITY_INVALID,  IEC61850_QUALITY_RESERVED and IEC61850_QUALITY_QUESTIONABLE) 	 */
#define IEC61850_QUALITY_BITMASK_VALIDITY 0xC000

#else

/*!	IEC61850 Quality flags. (see IEC 61850-8-1:2004 section 8.2) */
enum IEC61850QualityFlags
{
	IEC61850_QUALITY_GOOD			= 0x0000,	/*!< Good */
	IEC61850_QUALITY_INVALID		= 0x0040,	/*!< Invalid */
	IEC61850_QUALITY_RESERVED		= 0x00080,	/*!< Reserved */
	IEC61850_QUALITY_QUESTIONABLE	= 0x00C0,	/*!< Questionable */
	IEC61850_QUALITY_OVERFLOW		= 0x0020,	/*!< Overflow */
	IEC61850_QUALITY_OUTOFRANGE 	= 0x0010,	/*!< Out of Range */
	IEC61850_QUALITY_BADREFERENCE	= 0x0008,	/*!< Bad Reference */
	IEC61850_QUALITY_OSCILLATORY	= 0x0004,	/*!< Oscillatory */
	IEC61850_QUALITY_FAILURE		= 0x0002,	/*!< Failure */
	IEC61850_QUALITY_OLDDATA		= 0x0001,	/*!< Old Data */
#if defined (__PARADIGM__) /* Need to typecast to int on BECK RTOS on 16bit SC1x3 CPU due to enums being stored in 16bit signed integer */ 
	IEC61850_QUALITY_INCONSISTENT			= (int)0x8000,	/*!< Inconsistent */
#else
	IEC61850_QUALITY_INCONSISTENT	= 0x8000,	/*!< Inconsistent */
#endif
	IEC61850_QUALITY_INACCURATE		= 0x4000,	/*!< Inaccurate */
	IEC61850_QUALITY_SUBSTITUED		= 0x2000,	/*!< Substitued if not set then Source is from the process */
	IEC61850_QUALITY_TEST			= 0x1000,	/*!< Test */
	IEC61850_QUALITY_OPERATOR_BLOCKED	= 0x0800,	/*!< Blocked by Operator */
	IEC61850_QUALITY_SV_DER	= 0x0400,	/*!< Derived Quality for Sampled Values ONLY, Der field is an identifier of the derived current sampled value. Der should be set when the value is calculated and not a measurement - defined in 9-2LE*/
};

/*!	\brief  	Bit mask of Validity flags (IEC61850_QUALITY_GOOD, IEC61850_QUALITY_INVALID,  IEC61850_QUALITY_RESERVED and IEC61850_QUALITY_QUESTIONABLE) 	 */
#define IEC61850_QUALITY_BITMASK_VALIDITY 0x00C0

#endif // BigEndian


/*!	\brief  	Number of bits used in  Enum 	 */
#define IEC61850_ENUM_BITSIZE	8

/*!	\brief 	IEC61850 Enumerated data type. (as specified in IEC61850_DATATYPE_ENUMERATED or IEC61850_DATATYPE_CODED_ENUM) */
typedef Unsigned8 tIEC61850Enum;

/*!	\brief  Datatype of 	 Double position type	 */
#define IEC61850_DATATYPE_DBPOS  IEC61850_DATATYPE_INT8U

/*!	\brief  	Number of bits used in a Double position type (IEC61850_DATATYPE_DBPOS) 	 */
#define IEC61850_DBPOS_BITSIZE	8

/*!	enumerated value of double position as defined in IEC 61850 */
enum DbPosValues
{
	DBPOS_INTERMEDIATE	= 0,	/*!< intermediate  */
	DBPOS_OFF = 1,	/*!< off */
	DBPOS_ON = 2,	/*!< on */
	DBPOS_BAD = 3,	/*!< bad */
};


/*!	Values of double point (e.g. for Dbpos.stVal) to be provided by update callback */
enum IEC61850DbPosValues
{
	IEC61850_DB_POS_OFF		= 0x00,	/*!< Double Position is intermediate state  */
	IEC61850_DB_POS_FALSE	= 0x40,	/*!< Double Position is false/open */
	IEC61850_DB_POS_TRUE	= 0x80,	/*!< Double Position is close/true */
	IEC61850_DB_POS_INVALID	= 0xC0,	/*!< Double Position is in a bad or invalid state */
};

/*!    The states of Mode and Behavior (see 61850-7-4 IEC:2003 page 80)*/
enum IEC61850_ModeAndBehaviourStates
{
	IEC61850_MODE_ON  = 1, /*!<  Normal state. */
	IEC61850_MODE_BLOCKED 	 = 2, /*!<  Process is passively supervised. */
	IEC61850_MODE_TEST  = 3, /*!<  Function is operated but results are indicated as test results. */
	IEC61850_MODE_TESTBLOCKED 	= 4, /*!<  Function is operated in test mode but with no impact to the process.  */
	IEC61850_MODE_OFF = 5, /*!<  Function is inactive but shows its configuration capability. */
};

/*!    The states of Health (see 61850-7-4 IEC:2003 page 75) */
enum IEC61850_HealthStates
{
	IEC61850_HEALTH_OK	= 1,		/*!< OK ("Green") No problems, normal operation   */
	IEC61850_HEALTH_WARNING	= 2,		/*!< Warning (�yellow ? minor problems, but in safe operation mode */
	IEC61850_HEALTH_ALARM = 3,		/*!< Alarm (�red? severe problem, no operation possible */
};


/*!	\brief 		A Command Parameter structure. Used to exchange command parameters for Control commands between IEC61850 object and application. */
struct IEC61850_CommandParameters
{
	Boolean bTestMode; /*!< The current mode of the device, value must be from IEC61850_ModeAndBehaviourStates*/
	Integer8 iSyncroCheck;	/*!< If true (non 0), client has requested Syncro check be performed*/
	Integer8 iInterlockCheck; /*!< If true (non 0), client has requested Interlock check be performed*/
	Boolean bStackGenerated; /*!< The Callback has been generated by internal stack conditions, often set for cancel callbacks when the stack automatically removes a select on a control*/
	enum eOriginatorCat orCat;  /*!< The originator Category (orCat) that has been sent with the control to the server from the client*/
	const char * orIdent;  /*!< The originator Identity (orIdent) that has been sent with the control to the server from the client*/
	Unsigned8 orIdentSize; /*!< The size in bytes of the orIdent*/
	enum IEC61850_ModeAndBehaviourStates localBeh; /*!< the local Beh of the LN this control is in - if no beh is present the local Mod value will be used*/
};

struct IEC61850_Struct; // Forward Declaration of struct

/*!	\brief 	Pointer to an IEC61850 object */
typedef struct IEC61850_Struct* IEC61850;


/*!	Read Write and Update callbacks returned service error codes. (see IEC 61850-7-2:2003 section 5.5.3.4)  */
enum IEC61850_CallbackReturnServiceErrorCodes
{
	IEC61850_CB_ERROR_NONE									= 0,		/*!< Everything when OK */
	IEC61850_CB_ERROR_INSTANCE_NOT_AVAILABLE				= -1,		/*!< Action failed due to instance being not available */
	IEC61850_CB_ERROR_ACCESS_VIOLATION						= -2,		/*!< Action failed due to access violation */
	IEC61850_CB_ERROR_PARAMETER_VALUE_INCONSISTENT			= -3,		/*!< Action failed due to inconsistent parameter value */
	IEC61850_CB_ERROR_INSTANCE_LOCKED_BY_OTHER_CLIENT		= -4,		/*!< Action failed due to data locked by other client */
	IEC61850_CB_ERROR_TYPE_CONFLICT							= -5,		/*!< Action failed data type conflict */
	IEC61850_CB_ERROR_FAILED_DUE_TO_SERVER_CONSTRAINT		= -6,		/*!< Action failed due to server constraint */
};

/*!	Enumerated data type for command (controls) error codes */
enum eCommandAddCause
{
	IEC61850_COMMAND_ERROR_NONE 										= -1,		/*!< Control action successfully executed.  */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_UNKNOWN							= 0,		/*!< Default value. Command not successful due to Unknown causes */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_NOT_SUPPORTED						= 1,		/*!< Control action is not supported. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY		= 2,		/*!< Not successful since one of the downstream Loc switches like in CSWI has the value TRUE */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_SELECT_FAILED						= 3,		/*!< Canceled due to an unsuccessful selection (select service) */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_INVALID_POSITION					= 4,		/*!< Control action is aborted due to invalid switch position (Pos in XCBR or XSWI) */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_POSITION_REACHED					= 5,		/*!< Switch is already in the intended position (Pos in XCBR or XSWI) */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_PARAMETER_CHANGE_IN_EXECUTION		= 6,		/*!< Control action is blocked due to running parameter change. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_STEP_LIMIT							= 7,		/*!< Control action is blocked, because tap changer has reached the limit (EndPosR or EndPosL in YLTC). */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_MODE					= 8,		/*!< Control action is blocked, because the LN (CSWI or XCBR/XSWI) is in a mode (Mod) which doesn't allow any switching. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_PROCESS					= 9,		/*!< Control action is blocked due to some external event at process level that prevents a successful operation, for example blocking indication (EEHealth in XCBR or XSWI). */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_INTERLOCKING			= 10,		/*!< Control action is blocked due to interlocking of switching devices (in CILO attribute EnaOpn.stVal=�FALSE?or EnaCls.stVal=�FALSE?. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_SYNCHROCHECK			= 11,		/*!< Control action with synchrocheck is aborted due to exceed of time limit and missing synchronism condition. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_COMMAND_ALREADY_IN_EXECUTION		= 12,		/*!< Control, select or cancel service is rejected, because control action is already running.  */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_HEALTH					= 13,		/*!< Control action is blocked due to some internal event that prevents a successful operation (Health). */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_1_OF_N_CONTROL						= 14,		/*!< Control action is blocked, because another control action in a domain (for example substation) is already running (in any XCBR or XSWI of that domain, the DPC.stSeld=�TRUE?. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_ABORTION_BY_CANCEL					= 15,		/*!< Control action is aborted due to cancel service. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_TIME_LIMIT_OVER					= 16,		/*!< Control action is terminated due to exceed of some time limit. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_ABORTION_BY_TRIP					= 17,		/*!< Control action is aborted due to a trip (PTRC with ACT.general=�TRUE?. */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_OBJECT_NOT_SELECTED				= 18,		/*!< Control action is rejected, because control object was not selected */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_OBJECT_ALREADY_SELECTED			= 19,		/*!< Control action is rejected, because control object is already selected */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_NO_ACCESS_AUTHORITY				= 20,		/*!< Control action is rejected, because of no authority to access */
	IEC61850_COMMAND_ERROR_ADD_CAUSE_ENDED_WITH_OVERSHOOT				= 21,		/*!< Control action executed but the end position has overshoot*/
	IEC61850_COMMAND_ERROR_ADD_CAUSE_ABORTION_DUE_TO_DEVIATION			= 22,		/*!< Control action is aborted due to deviation between the command value and the measure value*/
	IEC61850_COMMAND_ERROR_ADD_CAUSE_ABORTION_BY_COMMUNICATION_LOSS		= 23,		/*!< Control action is aborted due to connection with client lost*/
	IEC61850_COMMAND_ERROR_ADD_CAUSE_BLOCKED_BY_COMMAND					= 24,		/*!< Control action is blocked due to data attribute CmdBlk.stVal = TRUE*/
	IEC61850_COMMAND_ERROR_ADD_CAUSE_NONE 								= 25,		/*!< Control action successfully executed.  */
	IEC61850_COMMAND_ERROR_ADD_INCONSISTENT_PARAMETER					= 26,		/*!< The parameter between successive control service is not consistent*/
	IEC61850_COMMAND_ERROR_ADD_LOCKED_BY_OTHER_CLIENT					= 27,		/*!< Another client has already reserved object*/
};

/*!    Server/client parameter  */
enum IEC61850_ClientServerFlag
{
	IEC61850_SERVER					= 0,		/*!< This IEC61850 Object is a Client */
	IEC61850_CLIENT					= 1,		/*!< This IEC61850 Object is a Server */
};

/*!    Edition1 / Edition2 parameter  */
enum IEC61850_Ed1_Ed2_Flag
{
	IEC61850_Edition1				= 0,		/*!< This IEC61850 Object is a Edition1 */
	IEC61850_Edition2				= 1,		/*!< This IEC61850 Object is a Edition2 */
};

/*!   Enum to set if you wish to load the last saved setting group data or not */
enum IEC61850_LoadSGDataFlag
{
	IEC61850_LOAD_LAST_SG_CHANGES	= 0,		/*!< If the SG Values are edited previously then SettingGroup values are loaded from persistent storage */
	IEC61850_IGNORE_SG_CHANGES		= 1,		/*!< Last SettingGroup changes are ignored */
};
enum IEC61850_DataMapMode
{
	IEC61850_MAP_MODE_DAID = 0,		
	IEC61850_MAP_MODE_SADDR = 1,		
	IEC61850_MAP_MODE_REFERENCE = 2,
};
/*!	Flags for struct IEC61850_Parameters.uiOptions flags */
enum IEC61850_OptionFlag
{
	IEC61850_OPTION_NONE							= 0x00,		/*!< No options set */
	IEC61850_OPTION_FLAG_TEST_MODE					= 0x01,		/*!< Set the test bit in outgoing GOOSE messages */
	IEC61850_OPTION_BLOCK_WRITE_TO_CF				= 0x02,		/*!< Block Write Access to Configuration fields */
	IEC61850_OPTION_SERVER_SEND_CONCLUDE_REQUEST	= 0x04,		/*!< Enables Server send conclude request to Client */
	IEC61850_OPTION_SERVER_SUBSCRIBE_GOOSE			= 0x08,		/*!< Enable the server to receive GOOSE messages*/
	IEC61850_OPTION_ALLOW_DUPLICATE_DAID			= 0x10,		/*!< Allows for duplicate DAID's in the CID file - WARNING: use with caution! This option can cause inconsistent and unexpected behavior */
	IEC61850_OPTION_UCA_TESTING						= 0x20,		/*!< Disables writing the DataUpdate Trigger option for Reports- WARNING: use with caution! This is for ED1 UCA testing only */
	IEC61850_OPTION_SLOW_LOAD						= 0x40,		/*!< Adds a sleep to the process of reading the ICD file so that other applications can take priority away. This will dramatically slow the loading of large ICD files. */
	IEC61850_OPTION_SYSTEMCORP_RESERVED				= 0x80,		/*!< SystemCORP Reserved please do not  use */
	IEC61850_OPTION_DEFAULT_INDEXED_REPORTING_FALSE	= 0x100,	/*!< Sets the default value for the Indexed flag with reports to FALSE */
	IEC61850_OPTION_DISABLE_AUTO_FEEDBACK_CMD_TERM	= 0x200,	/*!< Setting this will stop the stack from automatically sending command termination when a controls feedback value (stVal) is set to the desired position, instead it will wait for the full oper time to elapse */
	IEC61850_OPTION_DISABLE_CONTROL_CFDC_READ_ONLY  = 0x400,	/*!< This flag will stop the stack making all data points with FC = CF or DC read only if no valkind is set - for example ctlModel, for strict conformance with the IEC61850 standard this should be enabled */
};

#define IEC61850_FILENAME_SIZE			256	//!< Maximum filename length
#define IEC61850_GENERALIZED_TIME_SIZE	30	//!< String length of the generalized time structure (ISO 8601 date without separators, e.g. YYYYMMDDHHMMSShhmmss.fffZ) including nul-terminator

/*!	\brief 		File attributes structure  */
struct tFile
{
	char		cFileName[IEC61850_FILENAME_SIZE];				/*!< Name of the file (name to retrieve, send, or listed in directory) */
	char		ctLastModified[IEC61850_GENERALIZED_TIME_SIZE];	/*!< Last modified date for the file described as ISO 8601 date without separators and ends in Z to denote UTC time, e.g. YYYYMMDDHHMMSShhmmss.fffZ*/
	Unsigned32	u32FileSize;			/*!< Size of the file */

	Boolean		bDirectory;				/*!< Used in file callbacks; Indicative flag for whether this file is a directory*/
	Boolean		bHide;					/*!< Used in file callbacks; Set to TRUE to hide this value from the requestor */
};

/*!	\brief		List of directory entries structure */
struct tFileAttr
{
	struct tFile primaryFile;					/*!< Used in file callbacks; The primary file or directory indicated in the request */
	struct tFile *ptArrayofDirectoryEntries;	/*!< Array of file structures containing the attributes retrieved */
	Unsigned32 u32NumOfDirectoryEntries;		/*!< Number of file entries retrieved from server */
};

/*! \brief		The type of file call */
enum IEC61850_FileCallType
{
	IEC61850_FILE_CALL_READ				= 1,	//!< Open the file for reading. - Called on the client if SetFile service is being used the ptArrayofDirectoryEntries will contain the file name sent from the client in the setfile service 
	IEC61850_FILE_CALL_GET_ATTRIBUTES	= 2,	//!< Get attributes of a file or directory.		Callback: Files can be hidden by setting the attribute in the file structure.
	IEC61850_FILE_CALL_DELETE			= 3,	//!< Delete a server file.
	IEC61850_FILE_CALL_SET_FILE			= 4,	//!< Request that the server download a file from the client.	Callback: The primary file is the local file, and the directory entries list contains the single remote filename
	IEC61850_FILE_CALL_SET_FILE_COMPLETE	= 5,	//!< Used when the SetFile transfer has successfully completed.		Callback: The primary file is the local file, and the directory entries list contains the single remote filename
	IEC61850_FILE_CALL_SET_FILE_FAIL	= 6,	//!< Used when the SetFile transfer has failed.		Callback: The primary file is the local file, and the directory entries list contains the single remote filename
};

/*! \brief		The type of file response */
enum IEC61850_FileResponseCode
{
	IEC61850_FILE_RESPONSE_ACCEPT			= 0,	//!< Accept the file request
	IEC61850_FILE_RESPONSE_ACCESS_DENIED	= 1,	//!< Access to file is denied
	IEC61850_FILE_RESPONSE_NON_EXISTENT		= 2,	//!< Pretend the file or directory does not exist
};

/*!	\brief Read Callback definition.  <br>
		   Read Callback will be called when an MMS read is performed on a DO or DA in the server,  <br>
		   if a DO is read the callback is called for each sub DA <br>
		   Callback is only called for DAs with a private ID attached 

	\ingroup 	ServerCallback

	\param[in] 	ptUserData				User specified data pointer 
	\param[in] 	ptDataAttributeID		Pointer to Data Attribute ID being read
	\param[in]	ptReturnedValue			Pointer to value from the stacks database. 
										It's not recomeneded to change the data value in the callback as this will not trigger DA events such as goose or reports, use IEC61850_Update() for this instead

	\return 	#IEC61850_CB_ERROR_NONE on success or a relevant value from enum #IEC61850_CallbackReturnServiceErrorCodes

	\see IEC61850_SetUserData() , IEC61850_Update()
*/
typedef enum IEC61850_CallbackReturnServiceErrorCodes (*IEC61850_ReadCallback)(void * ptUserData, const void * pvDataMap, struct IEC61850_DataAttributeData * ptReturnedValue);

/*!	\brief 	Read Multiple Callback definition.  <br> - If this callback is defined, the IEC61850_ReadCallback will not be used. <br>
		   Read Multiple Callback will be called when an MMS read is performed on a DO or DA in the server, <br>
		   If a DO is read the callback is called with an array of ID and values with each sub DA as an element  <br>
		   Callback is only called for DAs with a private ID attached  

	\ingroup 	ServerCallback

	\param[in] 	ptUserData				User specified data
	\param[in] 	ptDataAttributeID		Array of Data Attribute ID's being read
	\param[in]	ptReturnedValue			Array of values being returned to read request. If these values are changed in your callback, this will be sent to the client performing the read *not recomended*
	\param[in]	iCount					The number of elements in the ptReturnedValue and ptDataAttributeID Arrays 

	\return 	#IEC61850_CB_ERROR_NONE on success or a relevant value from enum #IEC61850_CallbackReturnServiceErrorCodes
	
	\see IEC61850_SetUserData()
*/
typedef enum IEC61850_CallbackReturnServiceErrorCodes (*IEC61850_ReadMultipleCallback)(void * ptUserData, const void* pvDataMap, struct IEC61850_DataAttributeData * ptReturnedValue, int iCount);


/*!	\brief Write callback definition <br> <br>
		   Write Callback will be called when an MMS write is performed on a DO or DA in the server, <br>
		   if a DO is written the callback is called for each sub DA <br>
		   Callback is only called for DAs with a private ID attached  

	\ingroup 	ServerCallback

	\param[in] 	ptUserData				User specified data pointer 
	\param[in] 	ptDataAttributeID		Pointer to Data Attribute ID being written 
	\param[in]	ptNewValue			Pointer to value being written.

	\return 	#IEC61850_CB_ERROR_NONE to accept the new value or relevant value from enum #IEC61850_CallbackReturnServiceErrorCodes to reject the write

	\see IEC61850_SetUserData()
*/
typedef enum IEC61850_CallbackReturnServiceErrorCodes (*IEC61850_WriteCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptNewValue);


/*!	\brief Update callback definition <br>
		   Update callback will be called when data is received on the server or client from GOOSE or Reports <br>
		   Callback is only called for DAs with a private ID attached  

	\ingroup 	ServerAndClientCallback

	\param[in] 	ptUserData				User specified data pointer 
	\param[in] 	ptDataAttributeID		Pointer to Data Attribute ID being updated
	\param[in]	ptNewValue			Pointer to value being updated.

	\return 	none

	\see IEC61850_SetUserData()
*/
typedef void (*IEC61850_UpdateCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptNewValue);

typedef void (*IEC61850_ReportUpdateCallback)(void* ptUserData, const void* ptCBID, const void * ptNewValues,const unsigned int uiDataNum);

/*!	\brief DataPoint Questionable callback definition <br>
		   This callback is generated when the GOOSE communication to a remote server fails and the Time Allowed to Live (TAL) in the previous GOOSE packet has expired <br>
		   The callback is generated for each item in the GCB data set with an private ID attached <br>
		   It should be used in a client or Server IEDs with GOOSE subscription enabled.  

	\ingroup 	ServerAndClientCallback

	\param[in] 	ptUserData				User specified data pointer  
	\param[in] 	ptDataAttributeID		Pointer to Data Attribute ID that has expired and it's value should now be considered questionable 

	\return 	none

	\see IEC61850_SetUserData()
*/
typedef void (*IEC61850_DataPointQuestionableCallback)(void * ptUserData, const void* pvDataMap);


/*!	\brief Command Select Test CallBack <br>
			This optional callback is called when a Select Command is received, and is used to do pre-select tests, <br>
			For example interlock test to see if an interlocked control is already active, if so return ::IEC61850_COMMAND_ERROR_ADD_CAUSE_1_OF_N_CONTROL

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the Oper$CtlVal of this control.
	\param[in]	ptSelectTestParameters	Pointer to the IEC61850_CommandParameters structure  that contains control parameters such as orIdent, orCat, etc

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause(*IEC61850_ControlSelectTestCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_CommandParameters* ptSelectTestParameters);

/*!	\brief Command Select CallBack <br>
		   This callback is generated when a valid MMS Select has been received and the server is in a state where the control can be selected.

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer 
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the Oper$CtlVal of this control.
	\param[in]	ptSelectValue	Pointer to value of the select sent (SBO Enhanced security), Will be NULL if the select is SBO with normal security control model.
	\param[in] 	ptSelectParameters		Pointer to the IEC61850_CommandParameters structure  that contains control parameters such as orIdent, orCat, etc

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause (*IEC61850_ControlSelectCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptSelectValue, const struct IEC61850_CommandParameters* ptSelectParameters);


/*!	\brief Command Select Timeout CallBack <br>
		   This callback is generated when the internal logic in the stack has detected the control has timed out, <br>
		   This is generally due to the control not being operated after the sboTimeout value has elapsed.

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to an Array of Data Attribute ID control oper$ctlVal structure.
	\param[in]	ptCmdTermValue	Pointer to a DAData that contains a structure with the command termination data
								- the uiBitLength is the number of elements in the structure
								- pvData contains the control structures elements as an array of struct IEC61850_DataAttributeData items  (the number of items in the array is stored in uiBitLength).

	\return 	#IEC61850_COMMAND_ERROR_NONE - other values are ignored

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause(*IEC61850_ControlSelectTimeoutCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptSelectValue);

/*!	\brief Command Operative Test CallBack <br>
		   This optional callback is generated before the operate callback and is used to do pre-operate checks as defined in the IEC61850-7-2 ED2 section 20

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the Oper$CtlVal of this control.
	\param[in] 	ptOperativeTestParameters		Pointer to the IEC61850_CommandParameters structure  that contains control parameters such as orIdent, orCat, etc

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant enum #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause(*IEC61850_ControlOperativeTestCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_CommandParameters* ptOperativeTestParameters);


/*!	\brief Command Operate CallBack <br>
		   This callback is generated when a valid MMS Operate has been received and the server is in a state where the control can be Operated.

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer  
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the Oper$CtlVal of this control.
	\param[in]	ptOperateValue	Pointer to value of operate command that control is requested to be operated to.
	\param[in] 	ptOperateParameters		Pointer to the IEC61850_CommandParameters structure  that contains control parameters such as orIdent, orCat, etc

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant enum #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause (*IEC61850_ControlOperateCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptOperateValue, const struct IEC61850_CommandParameters* ptOperateParameters);


/*!	\brief Command Cancel CallBack <br>
		   This callback is generated when a valid MMS Cancel has been received and the server is in a state where the control can be canceled.

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the Oper$CtlVal of this control.
	\param[in] 	ptCancelParameters		Pointer to the IEC61850_CommandParameters structure  that contains control parameters such as orIdent, orCat, etc

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant enum #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause(*IEC61850_ControlCancelCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_CommandParameters* ptCancelParameters);


/*!	\brief Command Termination CallBack <br>
		   This callback is generated when a command termination from an enhanced security control has been received  <br>
		   it contains the control oper structure sent as the command termination and the ID's that match the data points. <br>
		   Note: Private IDs need to be set to elements in the oper structure for them to be included in this structure

	\ingroup 	ClientCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to an Array of Data Attribute ID control oper structure.
	\param[in]	ptCmdTermValue	Pointer to a DAData that contains a structure with the command termination data
								- the uiBitLength is the number of elements in the structure
								- pvData contains the control structures elements as an array of struct IEC61850_DataAttributeData items  (the number of items in the array is stored in uiBitLength).

	\return 	#IEC61850_COMMAND_ERROR_NONE if no error or relevant enum #eCommandAddCause error code

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause(*IEC61850_ControlCommandTerminationCallback)(void * ptUserData, const void* pvDataMap, const struct IEC61850_DataAttributeData * ptCmdTermValue);


/*!	\brief 	Error CallBack <br>
			This callback is generated when an IEC61850 LastApp error occurs, often in response to an Operate / Select / Cancel request 

	\ingroup 	ServerCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ptControlID		Pointer to Data Attribute ID of the CtlVal that generated the error for this control, i.e SBOw$CtlVal if a select error, Oper$CtlVal if control error, etc.
	\param[in]	ptErrorParamtrs	Pointer to the IEC61850_ErrorParameters structure  that contains error values such as Item Name, error type, error string , etc

	\return 	#IEC61850_COMMAND_ERROR_NONE - other values are ignored

	\see IEC61850_SetUserData()
*/
typedef enum eCommandAddCause (*IEC61850_ErrorCallback)(void * ptUserData, const void * pvDataMap,  const struct IEC61850_ErrorParameters * ptErrorParamtrs);

/*!	\brief 	 Connection Status Callback <br>
			This callback is generated when a connection or disconnection event occurs, including attempting a connection <br>
			This information is available directly via the IEC61850_GetConnectionsList() API function

	\ingroup 	ClientCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	ConnectedServersArray		Pointer to a struct IEC61850_ServerStatusArray that contains an array with information of each connection configured in the Client 

	\see IEC61850_SetUserData() , IEC61850_GetConnectionsList()
*/
typedef void (*IEC61850_ConnectionStatusCallback)(void * ptUserData, struct IEC61850_ServerStatusArray ConnectedServersArray);

/*! \brief Timestamp Callback - if the time returned is Null/Zero, it will take time from the OS*/

/*!	\brief 	 Connection Status Callback <br>
			This optional callback is generated when the current time is required by the stack <br>
			if set to NULL the stack will get the time from the system clock *Recommended* 

	\ingroup 	ServerandClientCallback

	\param[in] 	ptUserData		User specified data pointer
	\param[in] 	CurrentTime		Pointer to a struct IEC61850_TimeStamp to be populated in the callback with the current time

	\see IEC61850_SetUserData() 
*/
typedef void (*IEC61850_TimeStampCallback)(void * ptUserData, struct IEC61850_TimeStamp *CurrentTime);

/*!	\brief	File callback definition. Called when a file operation is requested. <br>
	\details	If this callback is not defined by the application, file reads and read attributes <br>
				are permitted on all files, and file deletion is rejected with error code ACCESS_DENIED. <br>

	\param[in] 	ptUserData				User specified data
	\param[in]	fileCallType			The type of file call requested
	\param[in]	ptFileAttributes		The information about the file(s) in question
	
	\return	The response code of type #IEC61850_FileResponseCode

	Example usage:
	\code
		enum IEC61850_FileResponseCode FileCallbackHandler(void * ptUserData, enum IEC61850_FileCallType fileCallType, struct tFileAttr* ptFileAttributes)
		{
			enum IEC61850_FileResponseCode responseCode = IEC61850_FILE_RESPONSE_ACCEPT;
			Unsigned32 fileIndex = 0;

			switch(fileCallType)
			{
				case IEC61850_FILE_CALL_READ:	//!< Open the server file for reading.
					printf("Open file: %s\n", ptFileAttributes->primaryFile.cFileName);
					break;
				case IEC61850_FILE_CALL_GET_ATTRIBUTES:	//!< Get attributes of a file or directory.		Callback: Files can be hidden by setting the attribute in the file structure.
					printf("Read file or directory attributes of '%s'\n", ptFileAttributes->primaryFile.cFileName);
					if(strcmp(ptFileAttributes->primaryFile.cFileName, "MySecretDirectory") == 0)
					{
						responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;
					}
					else
					{
						for(fileIndex = 0; fileIndex < ptFileAttributes->u32NumOfDirectoryEntries; fileIndex++)
						{
							struct tFile * pFile = &ptFileAttributes->ptArrayofDirectoryEntries[fileIndex];
							// Example of hiding files: Hide everything starting with P
							if(pFile->cFileName[0] == 'P')
							{
								pFile->bHide = TRUE;
							}
							// Print information
							printf(" Entry %4u %c Time %-20s Size %-7u  File %s\n", fileIndex, pFile->bHide ? 'H' : ' ', pFile->ctLastModified, pFile->u32FileSize, pFile->cFileName);
						}
					}
					break;
				case IEC61850_FILE_CALL_DELETE:	//!< Delete a server file.
					printf("Delete file '%s'\n", ptFileAttributes->primaryFile.cFileName);
					responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;
					break;
				case IEC61850_FILE_CALL_SET_FILE:	//!< Request that the server download a file from the client.	Callback: The primary file is the local file including path , and the directory entries list contains the remote filename
					PrintToLog("Set file from the client. Local file '%s', remote file '%s'\n", ptFileAttributes->primaryFile.cFileName, ptFileAttributes->ptArrayofDirectoryEntries[0].cFileName);
					//  ptFileAttributes->primaryFile.cFileName is where the file will be written to disk, this can be modified in this callback 
					responseCode = IEC61850_FILE_RESPONSE_ACCESS_DENIED;  // Need to return IEC61850_FILE_RESPONSE_ACCEPT to allow files to be sent to the server
					break;
				case IEC61850_FILE_CALL_SET_FILE_COMPLETE:	//!< Completed downloading file from the client.	Callback: The primary file is the local file, and the directory entries list contains the remote filename
					PrintToLog("Set file from the client completed successfully. Local file '%s', bytes written to disk '%u'\n", ptFileAttributes->primaryFile.cFileName, ptFileAttributes->primaryFile.u32FileSize);
					break;
				case IEC61850_FILE_CALL_SET_FILE_FAIL:	//!< Download a file from the client Failed - Partial file may be on the file system.  Callback: The primary file is the local file, and the directory entries list contains the remote filename
					PrintToLog("Set file from the client FAILED. Local file '%s', bytes written to disk '%u'\n", ptFileAttributes->primaryFile.cFileName, ptFileAttributes->primaryFile.u32FileSize);
					break;
				default:
					printf("Unknown file call type %d\n", fileCallType);
					break;
			}

			return responseCode;
		}
	\endcode
 */
typedef enum IEC61850_FileResponseCode (*IEC61850_FileCallback)(void * ptUserData, enum IEC61850_FileCallType fileCallType, struct tFileAttr* ptFileAttributes);
typedef void (*IEC61850_GooseReciveTimeCallback)(void* ptUserData, Unsigned16 u16APPID);
/*!	\brief 		structure used to override the default all file services enables in MMS initiate handling, when fileHandling is set in the services in SCL file */
struct fileServices
{
	Boolean SpecifyFileServices;	/*!< Set TRUE to use the values below in MMS initiate for FileHandling*/
	Boolean enableGetFile;			/*!< Set TRUE to enable GetFile in MMS initiate for FileHandling */
	Boolean enableSetFile;			/*!< Set TRUE to enable SetFile in MMS initiate for FileHandling */
	Boolean enablefileDelete;		/*!< Set TRUE to enable fileDelete in MMS initiate for FileHandling */
	Boolean enableFileDirectory;	/*!< Set TRUE to enable fileDirectory in MMS initiate for FileHandling */
	Boolean enableObtainFile;		/*!< Set TRUE to enable ObtainFile in MMS initiate for FileHandling */
};

/*!	\brief 		Create Server/client parameters structure used when calling IEC61850_Create()
	\see IEC61850_Create() 
*/
struct IEC61850_Parameters
{
	enum IEC61850_ClientServerFlag 				ClientServerFlag;			/*!< Flag set to indicate if this is to be a server  or a client  see #IEC61850_ClientServerFlag for values */
	enum IEC61850_Ed1_Ed2_Flag 		            Ed1_Ed2_Flag;				/*!< Flag set to indicate if this is to be a Edition1 or Edition 2  see #IEC61850_Ed1_Ed2_Flag for values */
	enum IEC61850_LoadSGDataFlag				LoadUpdatedSGDataFlag;	    /*!< Flag set if last edited SettingGroup values are to be ignored and use SG Values from SCL file  see #IEC61850_LoadSGDataFlag for values  */
	Unsigned16									uiMMSTimeout;				/*!< Time, in milliseconds, to wait for a MMS response after sending a MMS request, if 0, defaults to 400ms. For best results, set to a multiple of 10 ms*/
	char **										authArray;					/*!< An array that contains the Password for client to send when connecting to a server, leave as NULL if no Authentication is needed, this needs to be ordered in the same order as the IEDS in the CID file - ignoring the client IED- This data will be copied and can be freed after the IEC61850_Create() call */
	Unsigned32									authArraySize;				/*!< The number of elements in the authArray if it is not NULL*/
	Unsigned8									numGoosePubRepeatMinTAL;    /*!< The number of times the GOOSE Publisher will retransmit at the minimum TAL, for local regulatory compliance, if unsure set to 0*/
	const char *								fileHandlingRootDir;		/*!< The root directory that file handling services will base all server file request from, this must be a nul terminated string and less than 128 characters */
	Unsigned8									ServerDirectoryRootSubDirDepth; /*!< the max depth of sub directories from the Root directory that will will be returned when the server receives an ACSI ServerDirectory request - 0 will only return the Root directory */
	Integer16									defaultResvTms;				/*!< The default value to reserve a buffered report control block in seconds when no ResvTms is actively written by the client. if 0 a value of 60 seconds will be used*/
#ifndef __PARADIGM__
	unsigned int 								uiOptions;					/*!< Options flag, used to set client/server global options see #IEC61850_OptionFlag for values */
	int											iCmdTermTimeOut;			/*!< Command Termination time out in milliseconds . If 0 then defaults to 10000 milliseconds. This is the time that the stack will wait after receiving a valid operate command before evaluating command termination state.*/
	unsigned int								uiMaxServerAssociations; 	/*!< Specify Max number of Server Associations, If 0 then the default max number of associations will be set to 16 */
	unsigned int								uiMaxClientAssociations; 	/*!< Specify Max number of Client Associations, If 0 then the default max number of associations will be set to 16 */
#else
	unsigned long int 							uiOptions;					/*!< Options flag, used to set client/server global options see #IEC61850_OptionFlag for values */
	unsigned long int							iCmdTermTimeOut;			/*!< Command Termination time out in milliseconds . If 0 then defaults to 10000 milliseconds. This is the time that the stack will wait after receiving a valid operate command before evaluating command termination state */
	unsigned long int							uiMaxServerAssociations; 	/*!< Specify Max number of Associations, If 0 max number of associations will be set to 16 */
	unsigned long int							uiMaxClientAssociations; 	/*!< Specify Max number of Client Associations, If 0 then the default max number of associations will be set to 16 */
#endif
	Unsigned32									uiSettingGroupResvTimeOut;   /*!< Setting Group reservation time out in milliseconds. If 0 than defaults to 30000 milliseconds. This is the time that the stack will wait after receiving a valid Select Edit Setting Group message before discarding the edit buffer changes.*/
	struct fileServices							supportedFileService;		/*!< if SpecifyFileServices is set true then file handling will be enabled / disable and these services in the MMS initiate sequence - FileHandling in the IED services in the SCL needs to be present for file handling to be enabled*/
	
	IEC61850_ReadCallback						ptReadCallback;				/*!< Read callback function. Called when a read is performed on a data point in the client. If equal to NULL then callback is not used. */
	IEC61850_ReadMultipleCallback				ptReadMultipleCallback;		/*!< Read Multiple callback, if this is set, then IEC61850_ReadCallback() is not used.*/
	IEC61850_WriteCallback						ptWriteCallback;			/*!< Write callback function. If equal to NULL then callback is not used. */

	IEC61850_UpdateCallback						ptUpdateCallback;			/*!< Update callback function. Called when a data point is changed via a received Report, GOOSE or SV, If equal to NULL then callback is not used. */
	IEC61850_DataPointQuestionableCallback		ptQuestionableCallback;		/*!< Data point Questionable callback function, called when a data point is questionable from a GOOSE packet not being received before the Time Allowed to Live has expired  */

	IEC61850_ControlOperativeTestCallback		ptOprTestCallback;			/*!< Function called when a Operative Test  are performed on receiving Operate command, This is a recommended callback in an Edition 2 Server for */
	IEC61850_ControlSelectCallback				ptSelectCallback;			/*!< Function called when a Select (SBO) or Select with value (SBOw) command is executed */
	IEC61850_ControlOperateCallback				ptOperateCallback;			/*!< Function called when a Operate command has been received and passed pre-tests and ready to be executed */
	IEC61850_ControlCancelCallback				ptCancelCallback;			/*!< Function called when a Cancel command is executed */
	IEC61850_ControlCommandTerminationCallback	ptCmdTermCallback;			/*!< Function called when CommandTermination is received */
	IEC61850_ControlSelectTimeoutCallback		ptSelectTimeoutCallback;	/*!< Function called when a Select Timeout occurs on a selected control */
	IEC61850_ControlSelectTestCallback			ptSelectTestCallback;		/*!< Function called when a Select Command is recieved, and is used to do pre select tests, such as interlock test to see if an interlocked control is already active, if so return ::IEC61850_COMMAND_ERROR_ADD_CAUSE_1_OF_N_CONTROL  */

	IEC61850_ErrorCallback						ptErrorCallback;			/*!< Error Call back Function called when any error is received, such as a LastApp error from a control termination */
	IEC61850_ConnectionStatusCallback			ptConnectionStatusCallback; /*!< Function called when connection status changes, contains list of all configured connections and their state.*/
	IEC61850_TimeStampCallback					ptTimestampCallback;		/*!< Function called when the stack would generate a timestamp from the OS, allows for more accurate time sources to be used.*/
	IEC61850_FileCallback						ptFileCallback;				/*!< Function called when a file operation is requested */
	IEC61850_GooseReciveTimeCallback			ptGooseResvTimeOutback;
	enum IEC61850_DataMapMode                   DataMapMode;
	IEC61850_ReportUpdateCallback				ptReportUpdateCallback;
};

/*!	\brief 		IEC61850 Control Parameters */
struct IEC61850_ControlParameters
{
	Unsigned32 iTimeout;		/*!< Not Currently in use */
	Unsigned8 iSyncroCheck;		/*!< Should the server perform SyncroCheck? T/F*/
	Unsigned8 iInterlockCheck;	/*!< Should the server perform  Interlock Check? T/F*/
	Unsigned8 iTestFlag;		/*!< Control service tracking Test Flag to be sent */
};

/*!	\brief 		Generic time struct to use for calculating Time from Epoch */
struct IEC61850_DateTime {
	Unsigned32 tm_uSec;   /*!< Microseconds  */
	Unsigned8 tm_sec;   /*!< Seconds 0-59  */
	Unsigned8 tm_min;	  /*!< Minutes 0-59 */ 
	Unsigned8 tm_hour;  /*!< Hour 0-23 */
	Unsigned8 tm_mday;  /*!< Day 1-31 */
	Unsigned8 month;  /*!< Month 1-12  as opposed to usual tm_mon = 0-11. */
	Unsigned16 year;  /*!< Year */
};

/*!	\brief 		Remote Connections structure  */
struct RemoteConnection
{
	int		uiAAIndex;				/*!< connected server / client AA index */
	char	*ptDomainName;			/*!< domain name, Only available when PIS10 Stack is in client mode, will be NULL in Server mode*/
	char	*ptIPAddress;			/*!< IP Address of remote client / server*/
	Boolean	bConnectionState;		/*!< Connected state */
};

/*!	\brief 		Remote Connections List structure  */
struct ConnectionsList
{
	Unsigned16				u16NumberOfConnections;	/*!< Remote Connections count, i.e. the number of items in the ptConnections array */
	struct RemoteConnection *ptConnections;				/*!< Remote Connections list */
};

/*!	\brief 		GOOSEControlBlocks structure to get GOOSE CB information  */
struct GOOSEControlBlocks
{
	Boolean Enabled; /*!<Set True if this GOOSE CB is enabled */
	char* ptGoCBRef; /*!<A pointer to the GOOSE Control Blocks Reference*/
	Boolean isPublisher; /*!<Set True if this is a GOOSE Publisher control block, FALSE if this is a subscriber*/
	struct IEC61850_DataAttributeID ** ptDAIDArray; /*!<Array of Private IDs*/
	Unsigned32 ptDAIDArraySize; /*!<The numebr of elements in the ptDAIDArray;*/
};

/*!	\brief 		Data Attribute Information data structure for use in IEC61850_GetDataAttributesInfo() API   */
struct DAInfo
{
	struct IEC61850_DataAttributeID * DAID;  /*!< Private ID of data attribute */
	struct IEC61850_DataAttributeData DAData; /*!< Data information, pvData will be NULL on clients */
	char * name; /*!< Item Name on server, full MMS $ string on Client */
};

/*! \brief IEC61850 Log Entries structure. */
struct IEC61850_LogEntries
{
	struct IEC61850_LogEntry * logEntries;			/*!< Array of Log Entries */
	Unsigned32				   numberOfEntries; 	/*!< Number of entries in the logEntries Array */
	Boolean 				   bMoreFollows;		/*!< Flag indicating that more journal entries are available that given in this list */
};

/*! \brief IEC61850 Log Entry structure. */
struct IEC61850_LogEntry
{
	Unsigned8   entryID[8]; /*!< Entry ID */
	struct IEC61850_TimeStamp entryTime; /*!< Time that this entry was created */
	struct IEC61850_LogEntryData * logEntryData; /*!< Array of Data values in the entry */
	Unsigned32 numberOfLogEntryData; /*!< Number of variables listed in logEntryData Array */
};

/*! IEC61850 Reason codes as defined in IEC61850-8-1 section 8.1.3.11 */
enum IEC61850_ReasonCode
{
	IEC61850_RESERVED = 0, /*!< reserved to provide backward compatibility with UCA 2.0*/
	IEC61850_DATA_CHANGE = 1,
	IEC61850_QUALITY_CHANGE = 2,
	IEC61850_DATA_UPDATE = 3,
	IEC61850_INTEGRITY = 4,
	IEC61850_GENERAL_INTERROGATION = 5,
	IEC61850_APPLICATION_TRIGGER = 6,
};

/*! \brief IEC61850 Log Entry Data Value. */
//struct IEC61850_LogEntryData
//{
//	const struct IEC61850_DataAttributeID * logValueDAID; /*!< The Data Attribute ID of this entry data, may be NULL if no ID is set */
//	struct IEC61850_DataAttributeData  logValue; /*!< the Data Attribute Data value of this entry data */
//	enum IEC61850_ReasonCode reasconCode; /*!<The reason this data was included in the Log based on the Log Trigger options*/
//};
/*! \brief IEC61850 Log Entry Data Value. */
struct IEC61850_LogEntryData
{
	struct IEC61850_DataAttributeData  logValue; /*!< the Data Attribute Data value of this entry data */
	//struct  tDataItem* tData;  //
	char DataRef[OBJECT_REFERENCE_STRING_LEN + 1];
	char sFC[3];
	enum IEC61850_ReasonCode reasconCode; /*!<The reason this data was included in the Log based on the Log Trigger options*/
};

struct IEC61850_GetLogStatus_Result
{
	int iErrCode;
	struct IEC61850_LogStatus* ptLogStatus;
};
struct IEC61850_GetLogStatus_ResultList
{
	Unsigned32 uiNum;
	struct IEC61850_GetLogStatus_Result* ptLogStatusResults;
};
struct LogQueryParam   //
{
	char LogRef[OBJECT_REFERENCE_STRING_LEN + 1];
	struct TimeOfDay* StartTime;
	struct TimeOfDay* StopTime;
	Unsigned64 EntryID;
};
/*!  \brief IEC61850 Log Status Values structure. */
struct IEC61850_LogStatus
{
	struct IEC61850_TimeStamp OldestEntryTime; /*!< Oldest Entry Time in the log */
	struct IEC61850_TimeStamp NewestEntryTime;  /*!< Newest Entry Time in the log */
	Unsigned64 OldestEntry;  /*!< Oldest EntryID in the log */
	Unsigned64 NewestEntry;  /*!< Newest EntryID in the log */
};


/*!	\brief 			MMS Data Types	 */
enum eMMS_TypeDescription
{
	IEC_MMS_TYPE_ARRAY = 1,			/*!< Array of datatypes */
	IEC_MMS_TYPE_STRUCTURE = 2,			/*!< Structure of datatypes */
	IEC_MMS_TYPE_BOOLEAN = 3,			/*!< Boolean */
	IEC_MMS_TYPE_BITSTRING = 4,			/*!< Bitstring */
	IEC_MMS_TYPE_INTEGER = 5,			/*!< signed integer */
	IEC_MMS_TYPE_UNSIGNED = 6,			/*!< unsigned integer */
	IEC_MMS_TYPE_FLOATINGPOINT = 7,			/*!< floating point number */
	// 8 is Reserved
	IEC_MMS_TYPE_OCTET_STRING = 9,			/*!< string of octetls */
	IEC_MMS_TYPE_VISIBLE_STRING = 10,		/*!< string of visible charatures */
	IEC_MMS_TYPE_GENERALIZED_TIME = 11,		/*!< Gereralized time */
	IEC_MMS_TYPE_BINARY_TIME = 12,		/*!< MMS Binary Time */
	IEC_MMS_TYPE_BCD = 13,		/*!< Binary coded decimel */
	IEC_MMS_TYPE_OBJECT_ID = 15,		/*!< MMS Object ID */
	IEC_MMS_TYPE_MMS_STRING = 16,		/*!< MMS string of charatures */
	IEC_MMS_TYPE_UTC_TIME = 17,		/*!< 61850 UTC Time data */

	IEC_MMS_TYPE_BITSTRING_FIX_LENGTH = 118,		/*!< Fixed Length Bitstring - No Longer in use*/
	IEC_MMS_TYPE_MMS_STRING_FIX_LENGTH = 119,		/*!< MMS string of charatures with a fixed length */
	IEC_MMS_TYPE_OCTET_STRING_FIX_LENGTH = 120,		/*!< Fixed Length Octet string */
	IEC_MMS_TYPE_VISIBLE_STRING_FIX_LENGTH = 121,	/*!< Fixed Length Visiable String */
};

enum eReportSendDataReasonCode
{
	REPORT_SENDDATA_REASON_DATACHANGE = 0,
	REPORT_SENDDATA_REASON_INTEGRITY = 1,
};

/*!	\brief 	A Item of Data	 */
struct tMmsDataItem
{
	char			 			cType;			/*!< Type of data */
	int						iIndex;			/*!< Index specifier for Array Elements. */
	unsigned int		uiSize;			/*!< Size of data  */
	void* ptData;			/*!< Pointer to data */
};

#ifdef __cplusplus
}
#endif

#endif
// End of File
